package com.mt.vsphere.core.zhu.jpa;

import com.mt.vsphere.core.util.CommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.math.BigInteger;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Component
@Slf4j
public class JpaNativeSqlUtil {

    @PersistenceContext
    private EntityManager entityManagerBean;

    private static EntityManager entityManager;

    @Order(2)
    @PostConstruct
    public void init(){
        entityManager = entityManagerBean;
    }

    public static<T> List selectList(Class<?> t, String sql){
        Query query = entityManager.createNativeQuery(sql,t);
        return query.getResultList();
    }
    public static<T> Page<T> selectPage(Class<T> t, String sql , Pageable pageable){
        long start = pageable.getOffset();
        long size = pageable.getPageSize();

        Sort sort = pageable.getSort();
        String orderStr = StringUtils.collectionToDelimitedString(sort.stream().
                map(item-> CommonUtil.changeFieldToColumnName(item.getProperty())+" "+item.getDirection().name()).collect(Collectors.toList()), ",");
        if (!StringUtils.isEmpty(orderStr)) orderStr=" ORDER BY "+orderStr;
        String dataSql = sql+orderStr+" Limit "+ start+","+size;
        String countSql = sql.replaceAll("(SELECT).*?(FROM)","SELECT COUNT(1) FROM");
        Query countQuery = entityManager.createNativeQuery(countSql);
        Query dataQuery = entityManager.createNativeQuery(dataSql,t);
        long count = ((BigInteger) countQuery.getSingleResult()).longValue();
        List<T> content = count==0? Collections.emptyList() :dataQuery.getResultList();
        return new PageImpl<>(content,pageable,count);
    }
//
    public static<T> T selectObj(Class<?> t,String sql){
        Query query = entityManager.createNativeQuery(sql,t);
        return (T) query.getSingleResult();
    }

}
